<?php declare(strict_types=1);

namespace App\Api\Middleware;

use App\Api\Model\User;
use App\Api\Helper\JwtHelper;
use App\Constants\ErrorCode;
use App\Helper\RespHelper;
use Hyperf\Context\Context;
use App\Api\Constants\Business;
use Hyperf\HttpServer\Request;
use Hyperf\HttpServer\Response;
use Hyperf\Di\Annotation\Inject;
use App\Exception\BusinessException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Psr\Log\LoggerInterface;

class  AuthorizationMiddleware implements MiddlewareInterface
{

    #[Inject]
    protected Request $request;
    #[Inject]
    protected Response $response;

    protected LoggerInterface $logger;

    public function __construct()
    {
        $this->logger = getLogger('http-apis', 'middleware');
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        stdPrinter()->debug("[{$request->getMethod()}]:{$request->getUri()}_" . json_encode($this->request->all(), JSON_UNESCAPED_UNICODE));
        // 验证用户登录
        $this->validateLogin();
        return $handler->handle($request);
    }

    /**
     * 登录验证
     * @return void
     */
    private function validateLogin(): void
    {
        // 删除可能余留的用户信息上下文
        @Context::destroy(Business::CONTEXT_KEY_AUTH_USER);
        $authorization = $this->request->getHeader('authorization')[0] ?? null;
        // 当前被请求的接口路由
        $pathInfo = $this->request->getRequestUri();
        $authMember = null;
        empty($authorization) || $authMember = $this->getAuthMember($authorization);
        if ($pathInfo !== '/send_sms' && !$authMember) {
            // 登录状态验证失败，记录请求日志之后直接抛出异常
            $errorMsg = '当前未登录，请先登录';
            $schema = $this->request->getMethod() . ":" . $this->request->url();
            $this->logger->error($errorMsg . PHP_EOL . print_r([
                    'schema' => $schema,
                    'query' => formatLogArray($this->request->getQueryParams()),
                    'body' => $this->request->getParsedBody(),
                ], true));
            throw new BusinessException(ErrorCode::ERR_UNAUTHORIZED, $errorMsg);
        }
        if ($authMember instanceof User) {
            // 注册新的用户信息到请求上下文
            Context::set(Business::CONTEXT_KEY_AUTH_USER, $authMember);
        }
    }

    private function getAuthMember(string $token): ?User
    {
        if (empty($token)) return null;
        $jwtConfig = config('jwt.auth_apis');
        $jwtBody = JwtHelper::instance([$jwtConfig])->decode($token);
        if ($jwtBody && !empty($jwtBody['userid'])) {
            $userid = $jwtBody['userid'];
            $userid = 20000002;
            /** @var null|User $user */
            $user = User::findFromCache($userid);
            if ($user) return $user;
        }
        return null;
    }

}